#include "tanOR.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fstream>
#include <iostream>

#define GRID_STEP 2

/*
* Given camera and arg_max, find the extact 3D 2D point correspondence
* Reestimate the projection, and propose new proposal, but not put to the list
* I am not sure if this will work better or not;
*/
bool tanOR::argMax2(float P[][4],float cam_dir[3], int arg_max, tanParticle_s &tan_prop, float *p_template){
	/*return default value if this partilce should not be instantiated*/
	//	printf("id %d, arg_max: %d\n",id,arg_max);
	if(arg_max ==-1){
		tan_prop.score=0;
		tan_prop.arg_max_deformation=-1;
		tan_prop.response.clear();
		tan_prop.id = id;
		memset(&tan_prop.color_feature[0],0,sizeof(float)*30);
		return false;
	}

	/*clear particle*/
	tan_prop.pt_pairs.clear();
	tan_prop.response.clear();
	tan_prop.line_length.clear();

	int sx = p_img_data->sx;
	int sy = p_img_data->sy;
	float **M2_maps = p_img_data->M2map;

	float P_vec[12];
	/*put it into columnwise order*/
	for( int r = 0;r<3; ++r){
		for( int c = 0; c<4; ++c){
			P_vec[c*3+r]=P[r][c];
		}
	}

	/*
	* code below are from class shapeAndResponse
	*/
	lineVertex image_line;
	line matlab_line;
	int i_page,i_pix;
	float current_score=0;
	// update image projection matrix;
	this->camera.updateCamera(P_vec,cam_dir,1.f,1.f);
	if (!camera.isVisible()) {
		printf("proposed matrix not visible, will return");
		tan_prop.score = 0; 
		tan_prop.response.assign(tan_shape.line_list.size(),0.0f);
		tan_prop.arg_max_deformation   = -1;
		return false;
	}
	activeShape &current_shape = tan_shape;
	int i_deform = arg_max;
	deformation &current_deformation=current_shape.deformation_list[i_deform];


#ifdef SHOW_SHAPE_PROJECTION
	char name[512];
	sprintf(name,"../cache/image_%d_shape_%d_deform%d.pshape",i_img,i_shape,i_deform);
	svgDrawer drawer(n_orient);
	const char *p_name = const_cast<const char*> (name);
	drawer.newImage(p_name,p_Sy[i_img],p_Sx[i_img]);
#endif
	current_score = 0;
	assert(current_shape.line_list.size()==current_deformation.line_list.size());
	for(int i_line =0; i_line<current_shape.line_list.size();++i_line){
		lineVertex my_line = current_deformation.line_list[i_line];
		// compute score
		/*
		*conversion from plane line to image line, with both x axiss goes top-down, y axis goes left-right, 
		*so , image_line is not strictly following the image coordiate system we defined.
		*/
		camera.planeLineVertex2MatlabImage(my_line, image_line);
		// this is only convert the representation from struct line, to struct line2Vertex
		matlab_line=p_img_data->lineVertex2Line(image_line); 
		matlab_line.x = ROUND(matlab_line.x + 0.5f*sx+1);
		matlab_line.y = ROUND(matlab_line.y + 0.5f*sy+1);

		if (matlab_line.length>=n_length){
			// printf("line length greater than prepared %d\n",matlab_line.length);
			matlab_line.length = n_length-1;
		}


#ifdef SHOW_SHAPE_PROJECTION
		lineVertex tmp_line;
		tmp_line.x_end=image_line.y_end;
		tmp_line.x_start=image_line.y_start;
		tmp_line.y_end=image_line.x_end;
		tmp_line.y_start=image_line.x_start;
		drawer.pushLine(tmp_line);
#endif
		// check if out of boundary
		if(matlab_line.x<=0 || matlab_line.x>sx || matlab_line.y<=0 || matlab_line.y>sy ){
			//continue;
			printf("projected line segment out of bounary, will return\n");
			tan_prop.score = 0; 
			tan_prop.arg_max_deformation   = -1;	
			tan_prop.response.clear();
			tan_prop.line_length.clear();
			tan_prop.pt_pairs.clear();
			return false;
		}
		i_page=sub2IndS2(0,matlab_line.orient,0,matlab_line.length);
		i_pix = matlab_line.x-1+(matlab_line.y-1)*sx;



		assert(i_pix<sx*sy);
		assert(i_pix>=0);
		assert(i_page>=0);
		assert(i_page<n_length*n_orient*1);

#ifdef LENGTH_NORMALIZE
		float length = 2*matlab_line.length + 1.0f;
		current_score +=p_sk_weight[i_line]*M2_maps[i_page][i_pix]/length;
		tan_prop.response.push_back(M2_maps[i_page][i_pix]/length);
#else
		float line_score = M2_maps[i_page][i_pix];
		if(line_score<-1e6){
			printf( " line_score is reset to 0\n");
			line_score = 0;
		} 
		current_score +=p_sk_weight[i_line]*line_score;

		tan_prop.response.push_back(line_score);
		tan_prop.line_length.push_back(matlab_line.length);
#endif

		/*
		if(fabs(current_score)>1e6){
		current_score=0;
		printf("current_score is reset to 0, in argMax2\n");
		}
		*/

		/*find max line on S2 map, then convert the line into lineVertex Mode, and put to correspondence*/
		line max_line;
		shiftmax(matlab_line,max_line);
		lineVertex l2d=p_img_data->matlabLine2lineVertex(max_line);

		/*draw deformed template, if applicable*/
		if(p_template!=NULL){
			irac.drawDeformedLine(max_line,p_template);
		}

		/*correspondence should be points with nearest image distance*/

		pt_pair_s pt_pair_1,pt_pair_2;
		float d11 = (l2d.x_start-image_line.y_start)*(l2d.x_start-image_line.y_start)+(l2d.y_start-image_line.x_start)*(l2d.y_start-image_line.x_start);
		float d12 = (l2d.x_start-image_line.y_end)*(l2d.x_start-image_line.y_end)+(l2d.y_start-image_line.x_end)*(l2d.y_start-image_line.x_end);
		float d21 = (l2d.x_end-image_line.y_start)*(l2d.x_end-image_line.y_start)+(l2d.y_end-image_line.x_start)*(l2d.y_end-image_line.x_start);
		float d22 = (l2d.x_end-image_line.y_end)*(l2d.x_end-image_line.y_end)+(l2d.y_end-image_line.x_end)*(l2d.y_end-image_line.x_end);

		/*push the point correspondence, which are deformed 3D and deformed 2D points*/
		//tmp_pt_pair
		line3D L;
		assert(i_line<this->tan_shape.line_list.size());
		lineVertex &my_line_1=this->tan_shape.line_list[i_line];

		camera.planePoint2World(my_line_1.x_start,my_line_1.y_start,L.x1,L.y1,L.z1);
		camera.planePoint2World(my_line_1.x_end,my_line_1.y_end,L.x2,L.y2,L.z2);

		pt_pair_1[0]=L.x1;pt_pair_1[1]=L.y1;pt_pair_1[2]=L.z1;
		pt_pair_2[0]=L.x2;pt_pair_2[1]=L.y2;pt_pair_2[2]=L.z2;
		if(d11+d22<d12+d21){
			pt_pair_1[3]=l2d.x_start; pt_pair_1[4]=l2d.y_start;
			pt_pair_2[3]=l2d.x_end; pt_pair_2[4]=l2d.y_end;
		}else{
			pt_pair_1[3]=l2d.x_end; pt_pair_1[4]=l2d.y_end;
			pt_pair_2[3]=l2d.x_start; pt_pair_2[4]=l2d.y_start;
		}
		tan_prop.pt_pairs.push_back(pt_pair_1);
		tan_prop.pt_pairs.push_back(pt_pair_2);
	}// i line

#ifdef COMPLEXITY_NORMALIZE
	int num_segments=0;
	for(int i_line = 0; i_line<tan_prop.line_length.size();++i_line){
		num_segments += (tan_prop.line_length[i_line]*2+1);
	}

	current_score += num_segments *complexity_weight;
#endif

#ifdef USE_COLOR
	float color_score = this->testColor(arg_max,&(tan_prop.color_feature[0]));
	if(p_template!=NULL)
		drawColor(arg_max,p_template);
	current_score +=color_score;
#endif

#ifdef USE_FLAT
	float flat_score=this->testFlat(arg_max,&(tan_prop.flat_feature[0]));
	if(p_template!=NULL)
		drawFlat(arg_max,p_template);
	current_score +=flat_score;
#endif

	/*fill in the tan particle structure*/
	tan_prop.score=current_score;
	tan_prop.arg_max_deformation=arg_max;
	//this->camera.estimatePandDir(tan_prop.pt_pairs,tan_prop.P,tan_prop.cam_dir,tan_prop.fit_error);
	//this->camera.estimatePByPlaneInfo(tan_prop.pt_pairs,this->p_img_data->sy,this->p_img_data->sx,tan_prop.P,tan_prop.cam_dir,tan_prop.fit_error);
	tan_prop.id = this->id;
	return true;
}



/* for line(x, y, orientation = ind), find local maximum in image i */
float tanOR::shiftmax(const line &matlab_line,line &max_line){
	float m; /*maximum curve score*/
	int iPage;
	float **S2map = p_img_data->S2map;

	max_line.x = matlab_line.x;
	max_line.y = matlab_line.y;
	max_line.orient = matlab_line.orient;
	max_line.length = matlab_line.length;

	m = 2*NEGMAX;
	for(int dCurve2 = 0; dCurve2<=0; ++dCurve2){
		int currCurvature = 0 + dCurve2;
		/*currCurvature = 0 + dCurve2;
		currCurvature = MIN(currCurvature,nAngle-1);
		currCurvature = MAX(currCurvature,0);*/
		for(int dOri2 = -p_img_data->o_range2; dOri2<=p_img_data->o_range2; ++dOri2){
			int currOri = matlab_line.orient + dOri2;
			if (currOri<0)
				currOri += p_img_data->n_orient;
			else if (currOri>=p_img_data->n_orient)
				currOri -= p_img_data->n_orient;

			float alpha = PI*currOri/p_img_data->n_orient;
			for(int dLoc2 = p_img_data->l_range2; dLoc2>=-p_img_data->l_range2;--dLoc2){
				int x1 = matlab_line.x + floor(dLoc2*cos(alpha)+0.5f);
				int y1 = matlab_line.y + floor(dLoc2*sin(alpha)+0.5f);
				iPage = sub2IndS2(0,currOri,0,matlab_line.length);
				int here = x1-1+(y1-1)*p_img_data->sx;
				if(here<0||here>p_img_data->sx*p_img_data->sy)
					continue;
				if(S2map[iPage][here]>=m){
					m = S2map[iPage][here];
					max_line.x = x1; 
					max_line.y = y1; 
					max_line.orient= currOri; 
					max_line.length=matlab_line.length;
				}
			}
		}
	}
	return(m); 
}




float *tanOR::SWTest(view_s &view,bool use_color){
	int sx = p_img_data->sx;
	int sy = p_img_data->sy;
	float fx,fy; /*for projecting color model*/
	int x,y;

	float *max_score_map = new float[sx*sy];

	/*could be optimized*/
	for(int i =0; i<sx*sy; ++i){
		max_score_map[i]=NEGMAX;
	}

	/*Update camera and decide visibility*/
	float Pvec[12];
	for(int row = 0; row<3;++row){
		for( int col = 0; col<4; ++col){
			Pvec[row+col*3]=view.P[row][col];
		}
	}
	projector thread_safe_cam = this->camera;
	thread_safe_cam.updateCamera(Pvec,view.cam_dir,1.0f,1.0f);
	bool visible = thread_safe_cam.isVisible();
	if(!visible){
		//printf("current tan: %d is not visible.\n", this->id);
		memset(max_score_map,0,sx*sy*sizeof(float));
		return max_score_map;
	}

	float *score_map = new float[sx*sy];
	float *color_score_map = new float[sx*sy];
	float *mean_l_map = new float[sx*sy];
	float *mean_a_map = new float[sx*sy];
	float *mean_b_map = new float[sx*sy];
	float *var_l_map = new float[sx*sy];
	float *var_a_map = new float[sx*sy];
	float *var_b_map = new float[sx*sy];

	float *flat_score_map = new float[sx*sy];
	float *flat_mean_map = new float[sx*sy];
	float *flat_var_map = new float[sx*sy];

	lineVertex image_line;
	/*project and find the scanning window for each line segment*/
	int n_deform = tan_shape.deformation_list.size();
	int n_line = tan_shape.line_list.size();
	int n_pix = sx*sy;
	int map_size = n_pix;

	//variables used by color and flat
	int center_x;
	float coef, norm_const;
	float stat_score;
	int n_pt;
	for(int i_deform =0; i_deform<n_deform; ++i_deform){
		deformation &current_deformation = tan_shape.deformation_list[i_deform];
		int min_part_x = -NEGMAX;int min_part_y = -NEGMAX;
		int max_part_x = NEGMAX;int max_part_y = NEGMAX;
		int num_segments = 0;

		line *p_matlab_lines = new line[n_line];
		for(int i_line = 0; i_line<n_line; ++i_line){
			lineVertex &my_line = current_deformation.line_list[i_line];
			/*
			*conversion from plane line to image line, with both x axiss goes top-down, y axis goes left-right, 
			*so , image_line is not strictly following the image coordiate system we defined.
			*/
			thread_safe_cam.planeLineVertex2MatlabImage(my_line, image_line);
			// this is only convert the representation from struct line, to struct line2Vertex
			p_matlab_lines[i_line]=p_img_data->lineVertex2Line(image_line); 

			if (p_matlab_lines[i_line].length>=n_length){
				// printf("line length greater than prepared %d\n",matlab_line.length);
				p_matlab_lines[i_line].length = n_length-1;
			}
			num_segments += p_matlab_lines[i_line].length*2+1;

			// refine object bounding box
			// be careful since matlab_line is using x as top-down direction
			min_part_x = std::min(min_part_x,p_matlab_lines[i_line].y);
			min_part_y = std::min(min_part_y,p_matlab_lines[i_line].x);
			max_part_x = std::max(max_part_x,p_matlab_lines[i_line].y);
			max_part_y = std::max(max_part_y,p_matlab_lines[i_line].x);
		}/*i_line*/

		/*together with the object bounding box, we decide the range of sliding window operation*/
		min_part_x = std::min((int)floor(view.min_x), min_part_x);
		min_part_y = std::min((int)floor(view.min_y), min_part_y);
		max_part_x = std::max((int)ceil(view.max_x), max_part_x);
		max_part_y = std::max((int)ceil(view.max_y), max_part_y);

		int off_x = min_part_x%GRID_STEP; // make the starting point on the sub-sampled grid
		int off_y = min_part_y%GRID_STEP;
		min_part_x = min_part_x + GRID_STEP-off_x;
		min_part_y = min_part_y + GRID_STEP-off_y;

#ifdef COMPLEXITY_NORMALIZE
		float complexity_score = complexity_weight * num_segments;
		for(int i = 0 ; i<n_pix; ++i){
			score_map[i]=complexity_score;
		}
#else
		memset(score_map,0,sizeof(float)*n_pix);
#endif		

		int i_center,i_stroke,i_center_stop;
		int i_page;
		float *pMap;
		int diff_stroke_center ;
		float weight;
		float inv_length,tmp_score; 

		int center_y_start = std::max(1,-min_part_x+1);
		int center_y_stop = std::min(sy,sy-max_part_x);
		int center_x_start =std::max(1, -min_part_y+1);
		int center_x_stop = std::min(sx,sx-max_part_y-1);

		for(int i_line = 0; i_line<n_line; ++i_line){	
			i_page=sub2IndS2(0,p_matlab_lines[i_line].orient,0,p_matlab_lines[i_line].length);
			pMap = this->p_img_data->M2map[i_page];
			diff_stroke_center = p_matlab_lines[i_line].x + sx * p_matlab_lines[i_line].y;
			weight = p_sk_weight[i_line];
#ifdef LENGTH_NORMALIZE
			weight = weight/(2*p_matlab_lines[i_line].length+1.0f);
#endif
			if(fabs(weight)<1e-4) continue;
			for(int center_y = center_y_start;center_y<center_y_stop; center_y+=GRID_STEP){
				i_center = (center_x_start-1)+(center_y-1)*sx;
				i_center_stop = center_x_stop-1 + (center_y-1)*sx;
				i_stroke = i_center + diff_stroke_center;

				for(; i_center<i_center_stop; i_center+=GRID_STEP,i_stroke+=GRID_STEP){ 
					assert(i_stroke<=sx*sy);	
					if(i_center<0||i_stroke<0||i_center>=map_size||i_stroke>=map_size) continue;
					score_map[i_center]+=weight*pMap[i_stroke];
				}/*center_x*/
			}/*center_y*/
		}/*i_line*/

#ifdef USE_COLOR
		if(use_color){
			/********************************************/
			/*   color score                            */
			/********************************************/
			memset(color_score_map,0,sizeof(float)*sx*sy);

			memset(mean_l_map,0,sizeof(float)*sx*sy);
			memset(mean_a_map,0,sizeof(float)*sx*sy);
			memset(mean_b_map,0,sizeof(float)*sx*sy);

			memset(var_l_map,0,sizeof(float)*sx*sy);
			memset(var_a_map,0,sizeof(float)*sx*sy);
			memset(var_b_map,0,sizeof(float)*sx*sy);	

			assert(color_deform_grid_x.size()==color_deform_grid_y.size());
			assert(color_gridX.size() == color_gridY.size());


			std::vector<float> &deform_grid_x = color_deform_grid_x[i_deform];
			std::vector<float> &deform_grid_y = color_deform_grid_y[i_deform];

			int n_pt = this->color_gridX.size();
			if (n_pt!=0){
				int l,a,b;
				/*compute statistics*/
				for(int i_pt = 0; i_pt<n_pt; ++i_pt){
					thread_safe_cam.planePoint2Image(deform_grid_x[i_pt],deform_grid_y[i_pt],fx,fy);
					/*fx and fy is in image coorindate, means x points left to right*/
					x =floor(fy);y =floor(fx);
					diff_stroke_center = x + y*sx;
					for(int center_y = center_y_start;center_y<center_y_stop; center_y+=GRID_STEP){
						/*check y boundary*/
						if(center_y+y<1||center_y+y>=sx) continue;
						i_center = (center_x_start-1)+(center_y-1)*sx;
						i_center_stop = center_x_stop-1 + (center_y-1)*sx;
						i_stroke = i_center + diff_stroke_center;
						for(; i_center<i_center_stop; i_center+=GRID_STEP,i_stroke+=GRID_STEP){
							if(i_stroke<0||i_stroke>=map_size) continue;
							l = p_img_data->color_l_map[i_stroke];
							a = p_img_data->color_a_map[i_stroke];
							b = p_img_data->color_b_map[i_stroke];

							assert(l>=0);assert(l<8);
							assert(a>7);assert(a<16);
							assert(b>15);assert(b<24);

							color_score_map[i_center]=color_score_map[i_center]+ clr_weight[l] + clr_weight[a] + clr_weight[b];

							mean_l_map[i_center] += l;
							mean_a_map[i_center] += (a-8);
							mean_b_map[i_center] += (b-16);

							var_l_map[i_center] += l*l;
							var_a_map[i_center] += (a-8)*(a-8);
							var_b_map[i_center] += (b-16)*(b-16);
						}/*center_x*/
					}/*center_y*/
				}/*ipt*/
				/*normalize statistics*/
				coef = 1.0f/n_pt;
				norm_const = 10*coef;
				for(int center_y =center_y_start; center_y<center_y_stop; center_y+=GRID_STEP){
					i_center = (center_x_start-1)+(center_y-1)*sx;
					i_center_stop = center_x_stop-1 + (center_y-1)*sx;
					for(;i_center<i_center_stop;i_center+=GRID_STEP){
						/*normalize histogram*/
						color_score_map[i_center]*=norm_const;

						/*normalize statistics*/
						mean_l_map[i_center] *=coef;
						mean_a_map[i_center] *=coef;
						mean_b_map[i_center] *=coef;

						var_l_map[i_center] *=coef;
						var_a_map[i_center] *=coef;
						var_b_map[i_center] *=coef;
						/*compute variance*/				
						var_l_map[i_center] = var_l_map[i_center] - mean_l_map[i_center]*mean_l_map[i_center];
						var_a_map[i_center] = var_a_map[i_center] - mean_a_map[i_center]*mean_a_map[i_center];
						var_b_map[i_center] = var_b_map[i_center] - mean_b_map[i_center]*mean_b_map[i_center];
						/*update score for mean and variance*/
						stat_score = clr_weight[24]*mean_l_map[i_center] + clr_weight[25]*mean_a_map[i_center] + clr_weight[26]*mean_b_map[i_center];
						stat_score = stat_score + clr_weight[27]*var_l_map[i_center] + clr_weight[28]*var_a_map[i_center] + clr_weight[29]*var_b_map[i_center];
						color_score_map[i_center]+=stat_score;
						score_map[i_center] +=color_score_map[i_center];	
					}
				}
			}/*if n_pt!=0*/
		}/*if use_color==true*/
#endif	



#ifdef USE_FLAT
		/********************************************/
		/*   flat score                            */
		/********************************************/
		memset(flat_score_map,0,sizeof(float)*sx*sy);

		memset(flat_mean_map,0,sizeof(float)*sx*sy);

		memset(flat_var_map,0,sizeof(float)*sx*sy);


		assert(flat_deform_grid_x.size()==flat_deform_grid_y.size());
		assert(flat_gridX.size() == flat_gridY.size());


		std::vector<float> &flat_deformed_grid_x = flat_deform_grid_x[i_deform];
		std::vector<float> &flat_deformed_grid_y = flat_deform_grid_y[i_deform];

		n_pt = this->flat_gridX.size();
		if (n_pt!=0){
			int flat;
			/*compute statistics*/
			for(int i_pt = 0; i_pt<n_pt; ++i_pt){
				thread_safe_cam.planePoint2Image(flat_deformed_grid_x[i_pt],flat_deformed_grid_y[i_pt],fx,fy);
				/*fx and fy is in image coorindate, means x points left to right*/
				x =floor(fy);y =floor(fx);
				diff_stroke_center = x + y*sx;
				for(int center_y = center_y_start;center_y<center_y_stop; center_y+=GRID_STEP){
					/*check y boundary*/
					if(center_y+y<1||center_y+y>=sx) continue;
					i_center = (center_x_start-1)+(center_y-1)*sx;
					i_center_stop = center_x_stop-1 + (center_y-1)*sx;
					i_stroke = i_center + diff_stroke_center;
					for(; i_center<i_center_stop; i_center+=GRID_STEP,i_stroke+=GRID_STEP){
						if(i_stroke<0||i_stroke>=map_size) continue;
						int flat = p_img_data->mo_map[i_stroke];

						assert(flat>=0);assert(flat<8);

						flat_score_map[i_center]+= flat_weight[flat];
						flat_mean_map[i_center] += flat;
						flat_var_map[i_center] += flat*flat;
					}/*center_x*/
				}/*center_y*/
			}/*ipt*/
			/*normalize statistics*/
			coef = 1.0f/n_pt;
			norm_const = 10*coef;
			for(int center_y =center_y_start; center_y<center_y_stop; center_y+=GRID_STEP){
				i_center = (center_x_start-1)+(center_y-1)*sx;
				i_center_stop = center_x_stop-1 + (center_y-1)*sx;
				for(;i_center<i_center_stop;i_center+=GRID_STEP){
					/*normalize histogram*/
					flat_score_map[i_center]*=norm_const;

					/*normalize statistics*/
					flat_mean_map[i_center] *=coef;

					flat_var_map[i_center] *=coef;

					/*compute variance*/				
					flat_var_map[i_center] = flat_var_map[i_center] - flat_mean_map[i_center]*flat_mean_map[i_center];
					/*update score for mean and variance*/
					stat_score = flat_weight[8]*flat_mean_map[i_center];
					stat_score = stat_score + flat_weight[9]*flat_var_map[i_center];
					flat_score_map[i_center]+=stat_score;
					score_map[i_center] +=flat_score_map[i_center];	
				}
			}
		}/*if n_pt!=0*/
#endif

		/*Do the Max operations*/

		float *p_max,*p_score;
		for(int center_y =center_y_start; center_y<center_y_stop; center_y+=GRID_STEP){
			i_center = (center_x_start-1)+(center_y-1)*sx;
			i_center_stop = center_x_stop-1 + (center_y-1)*sx;
			for(;i_center<i_center_stop;i_center+=GRID_STEP){
				max_score_map[i_center]= std::max(max_score_map[i_center],score_map[i_center]);
			}
		}
		delete[] p_matlab_lines;
	}/*i_deform*/

	delete[] score_map;
	delete[] color_score_map;
	delete[] mean_l_map;
	delete[] mean_a_map;
	delete[] mean_b_map;
	delete[] var_l_map;
	delete[] var_a_map;
	delete[] var_b_map;

	delete[] flat_score_map;
	delete[] flat_mean_map;
	delete[] flat_var_map;

	/*set non-sliding window area to NEGMAX*/
	for(int i = 0; i<n_pix; ++i){
		//if(fabs(max_score_map[i])<1e-6 || fabs(max_score_map[i])>1e3)
		if( fabs(max_score_map[i])>1e3)
			max_score_map[i]=NEGMAX;
	}


	return max_score_map;
}



